#!/bin/bash
#
# Author:   Jacson RC Silva <jeiks@sistemaprolinux.com.br>
#
# $Id: fstabd. Last Update: Thu, 10 Jun 2010 14:12:20 -0300

### BEGIN INIT INFO
# Provides:          fstabd
# Required-Start:    $local_fs
# Required-Stop:     $local_fs
# Default-Start:     2
# Default-Stop:      0
# Short-Description: Script to detect partitions and insert them at /etc/fstab
# Description:       This script detects partitions and inserts them at /etc/fstab
### END INIT INFO


DESTINO='/media'
ARQ_TEMP='/tmp/fstabd'

# especifica se deve-se adicionar no fstab com UUID ou DEV
FSTAB_ADD_OPTION='DEV'

function log {
    echo -e "fstabd $(date +%X): $*" >> /var/log/syslog || true
    echo -e "fstabd: $*"
}

# obtem os dispositivos encontrados pelo kernel
function get_disp {
    devices=$( awk '{if ($3 !~ "ram*" && $3 !~ "loop*") print $3}' /proc/diskstats )
    #tratamento RAID
    echo "$devices" | grep "^md" || echo "$devices"
}

# verifica se o dispositivo existe no fstab
# retorna 0 caso verdadeiro
# primeiro parametro: dispositivo
# segundo parametro: y ou s para obter a linha do fstab
function existe_fstab {
    LOCAL_PARAM="-q"
    [ "$2" == "y" -o "$2" == "s" ] && LOCAL_PARAM=""
    grep $LOCAL_PARAM -e "^/dev/$1[[:blank:]]" -e "^UUID=$1[[:blank:]]" /etc/fstab
}

#cria o diretorio do parametro 1
function cria_dir {
    [ ! -d $DESTINO/$1 ] && mkdir -p $DESTINO/$1
}

# verifica dma, se o dispositivo tiver, retorna 0, caso contrario, 1
function verifica_dma {
    /sbin/hdparm /dev/$1 2>&1 | awk '{ if ($1 == "using_dma") print $3}' | grep -q 1
}

# recebe o dispositivo e tenta ativar o dma
# em caso positivo retorna 0
function ativa_dma {
    DISP=$1
    # verifica se esta ativado
    verifica_dma ${DISP} && return
    # tenta ativar usando hdparm
    hdparm -d1 /dev/${DISP} &> /dev/null
    #verifica se realmente ativou
    verifica_dma ${DISP} && return
}

# funcao retorna a nova linha com a tipo de arquivos modificado
# parametros: 1-> linha atual, 2-> novo tipo de arquivos
function troca_tipo_arq_linha {
    ATUAL=$( awk '{print $3}' <<< "$1" )
    NOVO="$2"
    awk '{print $1 "\t" $2 "\t" "'"$NOVO"'" "\t" $4 "\t" $5 "\t" $6}' <<< "$1"
}

# recebe dispositivo, tipo, algum parametro a mais parametros:
# 1-> dispositivo, 2-> tipo de arquivos, 3->UUID do dispositivo
function adiciona_dispositivo {
    DEV=$1
    TIPO=$2
    UUID=$3
    # se nao existir um dos parametros para
    # particoes que nao forem swap, ele sai da funcao
    [ -z "$DEV" -o -z "$TIPO" -o -z "$UUID" ] && [ "$TIPO" != "swap" ] && return

    case "$TIPO" in
        *swap*)
            MOUNT_POINT='none'
            TIPO="\t${TIPO}"
            OPT='sw'
            NUM='\t0\t0'
            log "Encontrada particao swap\t\t[\t${DEV}\t]";;
        *)
            # verifica se eh a raiz do sistema
            [ "$(awk '{if ($3 == "/") print $1}' /proc/mounts)" = "/dev/${DEV}" ] && {
                MOUNT_POINT="/"
                NUM='0\t1'
                OPT='errors=remount-ro'
            } || {
                MOUNT_POINT="${DESTINO}/${DEV}"
                NUM='0\t0'
                OPT='user,rw,sync,exec'
                cria_dir "${DEV}"
            }
            log "Encontrada particao     \t\t[\t${DEV}\t]";;
    esac
    #observacao para tipo ntfs
    if [ "$TIPO" = 'ntfs' ];then
        OPT="umask=022,${OPT}"
        TIPO="ntfs-3g"
    fi

    #somente para verificar se o tipo de arquivos esta corretamente especificado
    if existe_fstab "${DEV}" ||  existe_fstab "${UUID}";then
        log "  Verificando o tipo de arquivos de ${DEV}"
        case "$TIPO" in
            *swap*)
                    cmd="grep '^/dev/$DEV[[:blank:]]' /etc/fstab"
                    ;;
            *)
                    cmd="grep -e '^/dev/$DEV[[:blank:]]' -e '^UUID=$UUID[[:blank:]]' /etc/fstab"
                    ;;
        esac
        while read linha;do
            nova_linha=$(troca_tipo_arq_linha "$linha" $TIPO)
            sed -i "s;${linha};${nova_linha};" /etc/fstab
        done < <(bash -c "$cmd")
    else
        log "  Adicionando no fstab $1"
        if [ "$FSTAB_ADD_OPTION" == 'UUID' ];then
            echo -e "UUID=${UUID} \t${MOUNT_POINT} \t${TIPO} \t${OPT} \t${NUM}" >> /etc/fstab
        else
            echo -e "/dev/${DEV}\t${MOUNT_POINT} \t${TIPO} \t${OPT} \t${NUM}" >> /etc/fstab
        fi
    fi
}

# funcao para adicionar cdrom
function function_cdrom {
   MONT_P=$1
   ativa_dma $1
   existe_fstab "$1" && { 
        log "  CDROM presente no fstab       \t[\t$1\t]"
        #confirmando se o diretorio estah criado
        mkdir -p $(existe_fstab "$1" y | awk '{print $2}')
   } || {
        log "  Encontrado cdrom \t\t\t[\t$1\t]"
        echo -e "/dev/$1\t\t${DESTINO}/${MONT_P}\tudf,iso9660\t${3}user,noauto\t0 0" >> /etc/fstab
        cria_dir "${MONT_P}"
   }
}

# funcao para adicionar particoes
function function_hd {
    INFO=$(/usr/share/prolinux-fstabd/vol_id /dev/$1 2> /dev/null | grep -e 'USAGE=' -e 'TYPE=' -e 'UUID=')
    [ -z "$INFO" ] && return
    eval "$INFO"
    if [ "$ID_FS_USAGE" = 'filesystem' -o "$ID_FS_TYPE" = 'swap' ];then
        adiciona_dispositivo $1 $ID_FS_TYPE $ID_FS_UUID
    fi
}

# funcao para adicionar floppy
function function_floppy {
   MONT_P=$1
   grep "^/dev/$1[[:blank:]]" /etc/fstab >/dev/null && return
   FD="/dev/$1\t\t${DESTINO}/${MONT_P}\tauto\trw,user,sync,defaults 0 0"
   echo -e "${FD}" >> /etc/fstab
   cria_dir "$1"
   log "Encontrado disquete \t\t\t[\t$1\t]"
}

function limpa_fstab {
        DEVS=$(awk '$1 ~ /^\/|UUID/ {print $1}' /etc/fstab)
        for i in $DEVS;do
                case $i in
                        UUID=*)
                                if [ ! -L /dev/disk/by-uuid/${i#UUID=} ];then
                                        grep -v "^$i" /etc/fstab > /etc/fstab.new && \
                                                cp /etc/fstab.new /etc/fstab
                                fi
                        ;;
                        /dev*)
                                if ! grep -q ${i%/dev/} /proc/diskstats;then
                                        grep -v "^$i" /etc/fstab > /etc/fstab.new && \
                                                cp /etc/fstab.new /etc/fstab
                                fi
                        ;;
                esac
        done
        cat /etc/fstab
}

#######################
####  PRINCIPAL    ####
#######################
limpa_fstab
DISPOSITIVOS=$(get_disp)
for DISP in $DISPOSITIVOS; do
    case "$DISP" in
        # diquetes
        fd?)
            function_floppy "$DISP"
        ;;
        # outros dispositivos
        *)
            if grep -q cdrom /proc/ide/$DISP/media 2> /dev/null; then
                function_cdrom "$DISP"
	    elif /sbin/udevadm info -a -p $(/sbin/udevadm info -q path -n /dev/$DISP) | grep -q 'DRIVERS=="usb-storage"';then
		log "Dispositivo USB /dev/$DISP"
	    else
                function_hd "$DISP"
            fi
        ;;
    esac
done

# ativando o swap
swapon -a
